package com.witframework.web.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

/**
 * LoadingTag
 *
 * @author <a href="mailto:e.boudrant@cross-systems.com">Emmanuel Boudrant</a>
 *
 * LoadingTag: Simple tag used to display a loading message during an long, long
 * ... and long operation.<br>
 * <br>
 * <b>Use:</b><br>
 * <code><br>
 * &lt;tag:loading message="please wait..."&gt;<br>
 * LONG OPERATION !<br>
 * &lt;/tag:loading&gt;<br>
 * </code>
 */
public class LoadingTag extends TagSupport {

	// ----------------------------------------------------- Instance Variables

	/**
	 * Layer name, internal use only.
	 */
	private String name = null;

	/**
	 * Your message (note: can be HTML code).
	 */
	private String message = "Loading...";

	private String img=null;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {

		// Compute an unique layer name.
		name = System.currentTimeMillis() + "_" + Math.abs(message.hashCode());
		this.message = message;
	}

	/**
	 * Layer position style.
	 */
	private String position = "absolute";

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

	/**
	 * Layer X coord.
	 */
	private int left = 44;

	public String getLeft() {
		return left + "";
	}

	public void setLeft(String left) {
		this.left = Integer.parseInt(left);
	}

	/**
	 * Layer Y coord.
	 */
	private int top = 115;

	public String getTop() {
		return top + "";
	}

	public void setTop(String top) {
		this.top = Integer.parseInt(top);
	}

	/**
	 * Layer Widht.
	 */
	private int width = 300;

	public String getWidth() {
		return width + "";
	}

	public void setWidth(String width) {
		this.width = Integer.parseInt(width);
	}

	/**
	 * Layer Height.
	 */
	private int height = 300;

	public String getHeight() {
		return height + "";
	}

	public void setHeight(String height) {
		this.height = Integer.parseInt(height);
	}

	/**
	 * Layer Z position.
	 */
	private int zIndex = 1;

	public String getZIndex() {
		return zIndex + "";
	}

	public void setZIndex(String zIndex) {
		this.zIndex = Integer.parseInt(zIndex);
	}

	/**
	 * Layer tag (div,span,layer...).
	 */
	private String tag = "div";

	public String getTag() {
		return tag;
	}

	public void setTag(String tag) {
		this.tag = tag;
	}

	// --------------------------------------------------------- Public Methods

	/**
	 * Generate the layer message and flush output.
	 *
	 * @exception JspException
	 *                if a JSP exception has occurred
	 */
	public int doStartTag() throws JspException {

		StringBuffer results = new StringBuffer();

		boolean functionExist = Boolean.valueOf(
				(String) pageContext.getAttribute("functionExist",
						pageContext.REQUEST_SCOPE)).booleanValue();
		results.append("<!-- { LoadingTag.StartTag -->\n");
		// Do not overwrite the JavaScript function.
		if (!functionExist) {
			results.append("<script language=\"JavaScript\">\n");
			results.append("<!--\n");
			results.append("function _find_(n, d) { //v4.0\n");
			results
					.append("  var p,i,x;  if(!d) d=document; if((p=n.indexOf(\"?\"))>0&&parent.frames.length) {\n");
			results
					.append("    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}\n");
			results
					.append("  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];\n");
			results
					.append("  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=_find_(n,d.layers[i].document);\n");
			results
					.append("  if(!x && document.getElementById) x=document.getElementById(n); return x;\n");
			results.append("}\n");

			results.append("function _hide_() { //v3.0\n");
			results.append("  var i,p,v,obj,args=_hide_.arguments;\n");
			results
					.append("  for (i=0; i<(args.length-2); i+=3) if ((obj=_find_(args[i]))!=null) { v=args[i+2];\n");
			results
					.append("    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v='hide')?'hidden':v; }\n");
			results.append("    obj.visibility=v; }\n");
			results.append("}\n");
			results.append("//-->\n");
			results.append("</script>\n");

			pageContext.setAttribute("functionExist", "true",
					pageContext.REQUEST_SCOPE);

		}

		results.append("<" + tag + " id=\"" + name + "\" style=\"position:"
				+ position + "; width:" + width + "px; height:" + height
				+ "px; z-index:" + zIndex + "; left: " + left + "px; top: "
				+ top + "px\">\n");
		results.append(message + "\n");
		if(img!=null)
			results.append("<IMG src='"+img+"'>");
		results.append("</" + tag + ">\n");
		results.append("<!-- LoadingTag.StartTag  } -->\n");

		// Print this value to our output writer
		JspWriter writer = pageContext.getOut();
		try {
			writer.print(results.toString());
			writer.flush();
		} catch (IOException e) {
			throw new JspException("Print/Flush in LoadingTag tag error:" + e);
		}
		// Continue processing this page
		return (EVAL_BODY_INCLUDE);
	}

	/**
	 * Generate the javascript who hide the layer message.
	 *
	 * @exception JspException
	 *                if a JSP exception has occurred
	 */
	public int doEndTag() throws JspException {

		StringBuffer results = new StringBuffer();

		results.append("<!-- { LoadingTag.EndTag -->\n");
		results.append("<script language=\"JavaScript\">\n");
		results.append("_hide_('" + name + "','','hide')\n");
		results.append("</script>\n");
		results.append("<!-- LoadingTag.EndTag } -->\n");

		// Print this value to our output writer
		JspWriter writer = pageContext.getOut();
		try {
			writer.print(results.toString());
		} catch (IOException e) {
			throw new JspException("Print/Flush in LoadingTag tag error:" + e);
		}

		return (EVAL_PAGE);
	}

	/**
	 * Release any acquired resources.
	 */
	public void release() {

		super.release();
		message = null;
		name = null;
		position = null;

	}

	public String getImg() {
		return img;
	}

	public void setImg(String img) {
		this.img = img;
	}

}

